package org.shoukaiseki.common.cost;

import org.shoukaiseki.common.utils.CostMathUtils;
import org.shoukaiseki.common.utils.NumberUtils;

import java.math.BigDecimal;

import static org.shoukaiseki.common.utils.CostMathUtils.*;
import static org.shoukaiseki.common.utils.CostMathUtils.multiplyNullIsZero;

/**
 * 交易成本计算
 */
public class TransactionCostCalculation {

    /**
     * 本次交易数量,会从 orderTotalQuantity
     * 如果是反向操作(退库/退货),填写负数
     */
    private BigDecimal currentQuantity;

    /**
     * 本次交易成本
     * 计算后存放本次出库/退库,入库/退货的成本
     */
    private BigDecimal currentLineCost;

    /**
     * <pre>
     * 历史交易总数量
     * 如果计算退库/退货成本,实际正向(出库,入库)交易数量计算时需要用正数
     * </pre>
     */
    private BigDecimal historicalTransactionQuantity;

    /**
     * <pre>
     * 历史交易总成本
     * 如果计算退库/退货成本,实际正向(出库,入库)交易金额计算时需要用正数
     * </pre>
     */
    private BigDecimal historicalTransactionTotalCost;

    /**
     * 订单总数量
     */
    private BigDecimal orderTotalQuantity;

    /**
     * 订单总成本
     */
    private BigDecimal orderTotalCost;

    /**
     * <pre>
     * 超出订单数量时的基准单价
     *  调用前
     * </pre>
     */
    private BigDecimal overOrderUnitCost;

    /**
     * <pre>
     * 退回时超出历史交易数量时的基准单价
     * </pre>
     */
    private BigDecimal overTransactionUnitCost;

    public TransactionCostCalculation(){

    }

    public TransactionCostCalculation(BigDecimal currentQuantity, BigDecimal historicalTransactionQuantity, BigDecimal historicalTransactionTotalCost, BigDecimal orderTotalQuantity, BigDecimal orderTotalCost, BigDecimal overOrderUnitCost) {
        this.currentQuantity = currentQuantity;
        this.historicalTransactionQuantity = historicalTransactionQuantity;
        this.historicalTransactionTotalCost = historicalTransactionTotalCost;
        this.orderTotalQuantity = orderTotalQuantity;
        this.orderTotalCost = orderTotalCost;
        this.overOrderUnitCost = overOrderUnitCost;
    }

    public  BigDecimal calculateCurrentReduceCost(){
        currentLineCost = baseCalculateCurrentReduceCost();
        return currentLineCost;
    }

    public  BigDecimal baseCalculateCurrentReduceCost(){
//        if (isOverTransactionQuantity()) {
//            throw new MessageVirtualException("退库,退货不支持超过历史已入库出库数量");
//        }
        BigDecimal itemCost = CostMathUtils.divideNullIsZero(orderTotalCost, orderTotalQuantity, 6);
        BigDecimal currentLineCostTmp=BigDecimal.ZERO;
        if(overOrderUnitCost==null){
            overOrderUnitCost=itemCost;
        }
        if(overTransactionUnitCost==null){
            overTransactionUnitCost=itemCost;
        }
        if(NumberUtils.isGreaterZero(currentQuantity)) {
            BigDecimal remainingUntreatedQuantity=currentQuantity;
            BigDecimal sumCurrentLineCostTmp=BigDecimal.ZERO;
            CalculateScopeCost calculateScopeCost;
            if(NumberUtils.isLessZero(historicalTransactionQuantity)){
                //退回数量超过入库数量
                calculateScopeCost = new CalculateScopeCost(remainingUntreatedQuantity, historicalTransactionQuantity, historicalTransactionTotalCost,true);
                calculateScopeCost.calculateCurrentPositiveCost();
                remainingUntreatedQuantity = calculateScopeCost.getRemainingUntreatedQuantity();
                sumCurrentLineCostTmp=addNullIsZero(sumCurrentLineCostTmp,calculateScopeCost.getCalculateAfterCost());

                if (NumberUtils.isNullOrZero(remainingUntreatedQuantity)) {
                    return sumCurrentLineCostTmp;
                }

                calculateScopeCost = new CalculateScopeCost(remainingUntreatedQuantity, orderTotalQuantity, orderTotalCost,false);
                calculateScopeCost.calculateCurrentPositiveCost();
                remainingUntreatedQuantity = calculateScopeCost.getRemainingUntreatedQuantity();
                sumCurrentLineCostTmp=addNullIsZero(sumCurrentLineCostTmp,calculateScopeCost.getCalculateAfterCost());
            }else{
                calculateScopeCost = new CalculateScopeCost(remainingUntreatedQuantity, CostMathUtils.subtractNullIsZero(orderTotalQuantity,historicalTransactionQuantity), CostMathUtils.subtractNullIsZero(orderTotalCost,historicalTransactionTotalCost),false);
                calculateScopeCost.calculateCurrentPositiveCost();
                remainingUntreatedQuantity = calculateScopeCost.getRemainingUntreatedQuantity();
                sumCurrentLineCostTmp=addNullIsZero(sumCurrentLineCostTmp,calculateScopeCost.getCalculateAfterCost());
            }

            if (NumberUtils.isNullOrZero(remainingUntreatedQuantity)) {
                return sumCurrentLineCostTmp;
            }

            sumCurrentLineCostTmp=addNullIsZero(sumCurrentLineCostTmp,multiplyNullIsZero(remainingUntreatedQuantity,overOrderUnitCost));
            return sumCurrentLineCostTmp;



//
//
//            if (NumberUtils.isEquals(orderTotalQuantity, addNullIsZero(currentQuantity, historicalTransactionQuantity))) {
//                return subtractNullIsZero(orderTotalCost, historicalTransactionTotalCost);
//            }
//
//            if (NumberUtils.isLess(addNullIsZero(currentQuantity, historicalTransactionQuantity), orderTotalQuantity)) {
//                currentLineCostTmp = CostMathUtils.multiplyNullIsZero(itemCost, currentQuantity);
//                if (NumberUtils.compareToNullIsZero(CostMathUtils.addNullIsZero(currentLineCostTmp, historicalTransactionTotalCost), orderTotalCost) == 1) {
//                    currentLineCostTmp = subtractNullIsZero(subtractNullIsZero(orderTotalCost, historicalTransactionTotalCost), CostMathUtils.ZERO_POINT_ZERO_ONE);
//                    if (NumberUtils.isLessZero(currentLineCostTmp)) {
//                        currentLineCostTmp = subtractNullIsZero(orderTotalCost, historicalTransactionTotalCost);
//                    }
//                }
//                //本次成本加历史成本小于订单成本,直接返回
//                return currentLineCostTmp;
//            }
//            if (NumberUtils.isGreater(historicalTransactionTotalCost,orderTotalCost)) {
//                return CostMathUtils.multiplyNullIsZero(currentQuantity,overOrderUnitCost);
//            }

//            ((总数量-订单数量)*(入库超出单价)+订单总成本)-历史交易总成本
//            BigDecimal tmp=CostMathUtils.multiplyNullIsZero(subtractNullIsZero(addNullIsZero(historicalTransactionQuantity,currentQuantity),orderTotalQuantity),overOrderUnitCost);
//            currentLineCostTmp = subtractNullIsZero(addNullIsZero(tmp, orderTotalCost),historicalTransactionTotalCost);
//            return currentLineCostTmp;
        }else{
            //退回
            BigDecimal remainingUntreatedQuantity=currentQuantity;
            BigDecimal sumCurrentLineCostTmp=BigDecimal.ZERO;
            CalculateScopeCost calculateScopeCost = new CalculateScopeCost(remainingUntreatedQuantity, historicalTransactionQuantity, historicalTransactionTotalCost);
            calculateScopeCost.calculateCurrentReturnCost();
            remainingUntreatedQuantity = calculateScopeCost.getRemainingUntreatedQuantity();
            BigDecimal calculateAfterCost = calculateScopeCost.getCalculateAfterCost();
            sumCurrentLineCostTmp=addNullIsZero(sumCurrentLineCostTmp, calculateAfterCost);

            if (NumberUtils.isNullOrZero(remainingUntreatedQuantity)) {
                return sumCurrentLineCostTmp;
            }

            sumCurrentLineCostTmp=addNullIsZero(sumCurrentLineCostTmp,multiplyNullIsZero(remainingUntreatedQuantity,overTransactionUnitCost));
            return sumCurrentLineCostTmp;

//            if(!NumberUtils.isGreaterZero(orderTotalCost)){
//                //订单金额小于或等于0
////            本次数量*退回超出单价
//                return CostMathUtils.multiplyNullIsZero(currentQuantity,overTransactionUnitCost);
//            }

//            itemCost = CostMathUtils.divideNullIsZero(historicalTransactionTotalCost, historicalTransactionQuantity, 6);
//            if(NumberUtils.isEquals(NumberUtils.negateHasNull(currentQuantity),historicalTransactionQuantity)){
//                return historicalTransactionTotalCost;
//            }
//
//            if(NumberUtils.isGreater(NumberUtils.negateHasNull(currentQuantity),historicalTransactionQuantity)){
//                ((本次数量+历史数量)*退回超出单价-历史总成本)
//                currentLineCostTmp =subtractNullIsZero(multiplyNullIsZero(addNullIsZero(currentQuantity,historicalTransactionQuantity),overTransactionUnitCost),historicalTransactionTotalCost);
//                return currentLineCostTmp;
//            }else{
//                currentLineCostTmp = multiplyNullIsZero(currentQuantity, itemCost);
//                return  currentLineCostTmp;
//            }

        }
    }








    /**
     * 判断 入库/出库时 总交易数量是否超出订单数量
     * @return
     */
    public boolean isOverOrderQuantity(){
        if(NumberUtils.isGreaterZero(currentQuantity)){
            if(NumberUtils.isGreater(addNullIsZero(currentQuantity,historicalTransactionQuantity),orderTotalQuantity)){
                return true;
            }
        }
        return false;
    }

    /**
     * 判断 退货/退库时 总交易数量是否超出历史数量
     * @return
     */
    public boolean isOverTransactionQuantity(){
        if(NumberUtils.isLessZero(currentQuantity)){
            if(NumberUtils.isLessZero(addNullIsZero(currentQuantity,historicalTransactionQuantity))){
                return true;
            }
        }
        return false;
    }


    public BigDecimal getCurrentQuantity() {
        return currentQuantity;
    }

    public void setCurrentQuantity(BigDecimal currentQuantity) {
        this.currentQuantity = currentQuantity;
    }

    public BigDecimal getHistoricalTransactionQuantity() {
        return historicalTransactionQuantity;
    }

    public void setHistoricalTransactionQuantity(BigDecimal historicalTransactionQuantity) {
        this.historicalTransactionQuantity = historicalTransactionQuantity;
    }

    public BigDecimal getHistoricalTransactionTotalCost() {
        return historicalTransactionTotalCost;
    }

    public void setHistoricalTransactionTotalCost(BigDecimal historicalTransactionTotalCost) {
        this.historicalTransactionTotalCost = historicalTransactionTotalCost;
    }

    public BigDecimal getOrderTotalQuantity() {
        return orderTotalQuantity;
    }

    public void setOrderTotalQuantity(BigDecimal orderTotalQuantity) {
        this.orderTotalQuantity = orderTotalQuantity;
    }

    public BigDecimal getOrderTotalCost() {
        return orderTotalCost;
    }

    public void setOrderTotalCost(BigDecimal orderTotalCost) {
        this.orderTotalCost = orderTotalCost;
    }

    public BigDecimal getOverOrderUnitCost() {
        return overOrderUnitCost;
    }

    public void setOverOrderUnitCost(BigDecimal overOrderUnitCost) {
        this.overOrderUnitCost = overOrderUnitCost;
    }

    public BigDecimal getCurrentLineCost() {
        return currentLineCost;
    }

    public void setCurrentLineCost(BigDecimal currentLineCost) {
        this.currentLineCost = currentLineCost;
    }

    public BigDecimal getCurrentUnitCost() {
        return CostMathUtils.divideNullIsZero(currentLineCost,currentQuantity);
    }

    public BigDecimal getOverTransactionUnitCost() {
        return overTransactionUnitCost;
    }

    public void setOverTransactionUnitCost(BigDecimal overTransactionUnitCost) {
        this.overTransactionUnitCost = overTransactionUnitCost;
    }


}
